/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package wf.ui;

import bc.ds.Range;
import bc.dsl.SwingDSL;
import bc.swing.pfrm.BaseParamModel;
import bc.swing.pfrm.FieldParamModel.ChangeListener;
import bc.swing.pfrm.Model;
import bc.swing.pfrm.Page;
import bc.swing.pfrm.ano.Action;
import bc.swing.pfrm.ano.DataExtractor;
import bc.swing.pfrm.ano.DataInserter;
import bc.swing.pfrm.ano.PageDef;
import bc.swing.pfrm.ano.Param;
import bc.swing.pfrm.ano.ViewHints;
import bc.swing.pfrm.layouts.FormLayout;
import bc.swing.pfrm.models.NoDataModel;
import bc.swing.pfrm.viewtypes.ParamType;
import bc.utils.CalendarUtils.WeekDays;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;
import wf.model.Schedule;
import wf.model.Valve;
import wf.ui.layouts.SchedulingCreatorFormLayout;
import wf.ui.windows.Dialog;
import wf.units.DatabaseUnit;

/**
 *
 * @author bennyl
 */
@PageDef(name = "Create Schedule", icon = "Calendar64", layout = FormLayout.class)
public class ScheduleCreatorModifier extends Model {
    public static final String START_DATE_PARAM = "Start Date";
    public static final String END_DATE_PARAM = "End Date";
    public static final String PERIOD_MIN_PARAM = "Period(Min)";
    public static final String RECURRENCE_DATA_PARAM = "#Recurrence Data";
    public static final String RECURRENCE_PARAM = "Recurrence";
    public static final String VALVES_PARAM = "VALVES_PARAM";

    Schedule sc = new Schedule(0, new Date(), 123);
    Recurrence recurrence = Recurrence.None;
    Model recurrenceData = recurrence.getModel();
    Calendar endDate;
    Range period = new Range(0, 65535, 60);
    
    boolean accepted = false;

    public boolean isAccepted() {
        return accepted;
    }

    public ScheduleCreatorModifier() {
        endDate = Calendar.getInstance();
        endDate.add(Calendar.MONTH, 1);
    }
    
    @Param(name=VALVES_PARAM, type= ParamType.OPTIONS, num = -1)
    public List<Valve> getValves(){
        return DatabaseUnit.UNIT.selectAllValves();
    }
    
    public int getValveId() {
        return sc.getValveId();
    }

    public void setValveId(int valveId){
        sc.setValveId(valveId);
    }
    
    @Param(name = START_DATE_PARAM, type = ParamType.DATE_AND_TIME, num=0)
    public Calendar getDayTime() {
        Calendar cd = Calendar.getInstance();
        cd.setTime(sc.getDayTime());
        return cd;
    }
    
    public void setDayTime(Calendar cd) {
        sc.setDayTime(cd.getTime());
    }

    @Param(name=END_DATE_PARAM, type= ParamType.DATE_AND_TIME, num=1)
    public Calendar getEndDate() {
        return endDate;
    }
    
    public void setEndDate(Calendar endDate) {
        this.endDate = endDate;
    }

    @Param(name = PERIOD_MIN_PARAM, type = ParamType.NUMMERIC_RANGE, num=2)
    public Range getPeriodMinute() {
        return period;
    }
    
    @Param(name=RECURRENCE_PARAM, type= ParamType.OPTIONS, num=3)
    public Recurrence getRecurrence() {
        return recurrence;
    }

    @ViewHints(heightExpandPrecentage=100)
    @Param(name=RECURRENCE_DATA_PARAM, type= ParamType.PAGE, num=4)
    public Model getRecurrenceData() {
        return recurrenceData;
    }
    
    public void setRecurrence(Recurrence recurrence) {
        this.recurrence = recurrence;
    }

    @Override
    public void configurePageLayout(JPanel layout) {
        ((FormLayout)layout).setColorLabels(false);
    }
    
    
    @Action(name=Dialog.OK_ACTION)
    void handleOK(){
        syncFromView();
        setValveId(((Valve) getPage().getParam(VALVES_PARAM).getSelectedItem()).getId());
        accepted = true;
        getPage().disposeView();
    }
    
    @Action(name=Dialog.CANCEL_ACTION)
    void handleCANCEL(){
        accepted = false;
        getPage().disposeView();
    }

    public static void main(String[] args) {
        SwingDSL.configureUI();
        show();
    }
    
    @Override
    public void whenPageCreated(Page page) {
        page.getParam(RECURRENCE_PARAM).addSelectionListner(new ChangeListener() {

            @Override
            public void onChange(BaseParamModel source, Object newValue, Object deltaHint) {
                syncFromView(RECURRENCE_PARAM);
                recurrenceData = recurrence.getModel();
                syncToView(RECURRENCE_DATA_PARAM);
            }
        });
    }
    

    @PageDef(name = "Dayly Recurrence", layout = SchedulingCreatorFormLayout.class)
    public static class DayRecurrence extends Model {

        @Param(name = "Every$$days", type = ParamType.NUMMERIC_RANGE)
        public Range days = new Range(1, 365, 10);
    }
    
    @PageDef(name = "No Recurrence", layout = SchedulingCreatorFormLayout.class)
    public static class NoRecurrence extends Model {

        @Param(name = "#Message", type = ParamType.LABEL, icon="null")
        String msg = "No Recurrence Selected.";
    }

    @PageDef(name = "Weakly Recurrence", layout = SchedulingCreatorFormLayout.class)
    public static class WeeklyRecurrence extends Model {

        @Param(name = "Every$$weeks", type = ParamType.NUMMERIC_RANGE)
        public Range weeks = new Range(1, 100, 2);
        public Set<WeekDays> selectedDays = new HashSet<WeekDays>();

        @ViewHints(firstColumnWidth = 60, heightExpandPrecentage=100)
        @Param(name = "Week days", type = ParamType.TABLE)
        List<WeekDays> getDays() {
            return Arrays.<WeekDays>asList(WeekDays.values());
        }

        @DataExtractor(param = "Week days", columns = {"?", "Day"})
        Object extractDays(String c, WeekDays i) {
            if (c.equals("?")) {
                return selectedDays.contains(i);
            }
            return i.toString();
        }

        @DataInserter(param = "Week days", columns = {"?"})
        void inserttDays(String c, WeekDays i, boolean newVal) {
            if (newVal) {
                selectedDays.add(i);
            } else {
                selectedDays.remove(i);
            }
        }
    }

    @PageDef(name = "Monthly Recurrence", layout = SchedulingCreatorFormLayout.class)
    public static class MonthlyRecurrence extends Model {

        @Param(name = "Day", type = ParamType.NUMMERIC_RANGE)
        public Range day = new Range(1, 31, 10);
        
        @Param(name="Of every$$Month", type= ParamType.NUMMERIC_RANGE)
        public Range months = new Range(1, 100, 2);        
    }

    
    @PageDef(name = "Yearly Recurrence", layout = SchedulingCreatorFormLayout.class)
    public static class YearlyRecurrence extends Model {

        @Param(name = "on Day", type = ParamType.STRING)
        String day;
        
        @Param(name="Of Month", type= ParamType.STRING)
        String month;        
    }

    public static ScheduleCreatorModifier show(){
        final ScheduleCreatorModifier ret = new ScheduleCreatorModifier();
        Dialog.show(ret, 620, 320);
        return ret;
    }
    
    
    public static enum Recurrence{
        None(NoRecurrence.class),
        Dayly(DayRecurrence.class),
        Weekly(WeeklyRecurrence.class),
        Monthly(MonthlyRecurrence.class);
        
        Class model;

        private Recurrence(Class model) {
            this.model = model;
        }

        public Model getModel() {
            try {
                return  (Model) model.newInstance();
            } catch (InstantiationException ex) {
                Logger.getLogger(ScheduleCreatorModifier.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(ScheduleCreatorModifier.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            return new NoDataModel("Bad Thing Happend.. ");
        }
        
    }
}
